Use case: FIR or IIR (interrupt input X1, DMA output Y)

This use case shows an FMAC FIR/IIR filter where the X1 input FIFO is filled in interrupt mode and the Y output FIFO is read in DMA mode.

Sequence diagram

     @startuml
     title: FIR filter with :\n  - input/X1 managed with interrupt process \n  - output/Y managed with DMA process

     participant App as "User application"
     participant App
     participant "<font color=Black><b>HAL FMAC</b></font>" as FMAC
     participant "<font color=green><b>HAL DMA</b></font>" as DMA
     participant "FMACx_IRQHandler"
     participant "DMAx_IRQHandler"

     App -> FMAC : HAL_FMAC_Init()
     App <-- FMAC : HAL_OK

     group FMAC System initialization: can be called before FMAC HAL initialization
     App -[hidden]>FMAC
     end

     App -> FMAC : HAL_FMAC_FilterConfig()
     note right : The interrupt mode configuration for input X1 is carried out in this function by setting FMAC_BUFFER_ACCESS_IT\nin the InputAccess parameter within FMAC_FilterConfigTypeDef structure.\nThe DMA mode configuration for output Y is carried out in this function by setting FMAC_BUFFER_ACCESS_DMA\nin the OutputAccess parameter within FMAC_FilterConfigTypeDef structure.
     App <-- FMAC : HAL_OK

     App -> FMAC : HAL_FMAC_AppendFilterData()
     App <-- FMAC : HAL_OK

     App -> FMAC : HAL_FMAC_FilterStart()
     App <-- FMAC :HAL_OK

     FMAC <- "FMACx_IRQHandler" : HAL_FMAC_IRQHandler()
     FMAC --> "FMACx_IRQHandler"

     FMAC-> App : HAL_FMAC_GetDataCallback()
     FMAC<-- App

     "DMAx_IRQHandler" <- : DMAx half complete interrupt
     "DMAx_IRQHandler" -> "DMA" : HAL_DMA_IRQHandler()
     "DMA" -> FMAC : XferCpltCallback
     FMAC-> App : HAL_FMAC_HalfOutputDataReadyCallback()
     "DMA" <-- FMAC
     "DMAx_IRQHandler" <-- "DMA"
     "DMAx_IRQHandler" -->

     "DMAx_IRQHandler" <- : DMAx complete interrupt
     "DMAx_IRQHandler" -> "DMA" : HAL_DMA_IRQHandler()
     "DMA" -> FMAC : XferCpltCallback
     FMAC-> App : HAL_FMAC_OutputDataReadyCallback()
     "DMA" <-- FMAC
     "DMAx_IRQHandler" <-- "DMA"
     "DMAx_IRQHandler" -->

     App -> FMAC : HAL_FMAC_FilterStop()
     App <-- FMAC :HAL_OK

     App->FMAC : HAL_FMAC_DeInit()
     App<--FMAC

     @enduml

Code snippet

HAL1

HAL2

HAL_FMAC_Init(&hfmac)

sFmacConfig.InputBaseAddress  = INPUT_BUFFER_BASE;
sFmacConfig.InputBufferSize   = INPUT_BUFFER_SIZE;
sFmacConfig.InputThreshold    = INPUT_THRESHOLD;
sFmacConfig.CoeffBaseAddress  = COEFFICIENT_BUFFER_BASE;
sFmacConfig.CoeffBufferSize   = COEFFICIENT_BUFFER_SIZE;
sFmacConfig.OutputBaseAddress = OUTPUT_BUFFER_BASE;
sFmacConfig.OutputBufferSize  = OUTPUT_BUFFER_SIZE;
sFmacConfig.OutputThreshold   = OUTPUT_THRESHOLD;
sFmacConfig.pCoeffA           = aFilterCoeffA;
sFmacConfig.CoeffASize        = COEFF_VECTOR_A_SIZE;
sFmacConfig.pCoeffB           = aFilterCoeffB;
sFmacConfig.CoeffBSize        = COEFF_VECTOR_B_SIZE;
sFmacConfig.Filter            = FMAC_FUNC_IIR_DIRECT_FORM_1;
sFmacConfig.InputAccess       = FMAC_BUFFER_ACCESS_IT;
sFmacConfig.OutputAccess      = FMAC_BUFFER_ACCESS_DMA;
sFmacConfig.Clip              = FMAC_CLIP_DISABLED;
sFmacConfig.P                 = COEFF_VECTOR_B_SIZE;
sFmacConfig.Q                 = COEFF_VECTOR_A_SIZE;
sFmacConfig.R                 = GAIN;

HAL_FMAC_FilterConfig(&hfmac, &sFmacConfig);

HAL_FMAC_AppendFilterData(&hfmac, Input);
HAL_FMAC_FilterStart(&hfmac, Output, OutputDataSize);

HAL_FMAC_FilterStop(&hfmac);

HAL_FMAC_DeInit(&gh_fmac);
HAL_FMAC_Init(&hfmac, (hal_fmac_t)FMAC);

sFmacConfig.x1_buf.base_half_word = INPUT_BUFFER_BASE;
sFmacConfig.x1_buf.size_half_word = INPUT_BUFFER_SIZE;
sFmacConfig.x2_buf.base_half_word = COEFFICIENT_BUFFER_BASE;
sFmacConfig.x2_buf.size_half_word = COEFFICIENT_BUFFER_SIZE;
sFmacConfig.y_buf.base_half_word  = COEFFICIENT_BUFFER_SIZE;
sFmacConfig.y_buf.size_half_word  = OUTPUT_BUFFER_BASE;

HAL_FMAC_SetConfig(&hfmac, &sFmacConfig);

data.coeff_a_size_half_word = COEFF_VECTOR_A_SIZE;
data.p_coeff_a              = aFilterCoeffA;
data.coeff_b_size_half_word = COEFF_VECTOR_B_SIZE;
data.p_coeff_b              = aFilterCoeffB;

HAL_FMAC_PreloadX2(&hfmac, &data);

HAL_FMAC_WriteX1_IT(&hfmac, Input , size_half_word);
HAL_FMAC_ReadY_DMA(&hfmac, Output, OutputDataSize);

HAL_FMAC_StartFilterIIR(&hfmac, COEFF_VECTOR_B_SIZE, COEFF_VECTOR_A_SIZE, GAIN, HAL_FMAC_OPT_IT_FILTER_SATURATION_ERROR);

HAL_FMAC_StopFilter(&hfmac);

HAL_FMAC_DeInit(&gh_fmac);

Key changes

  1. HAL2 replaces the HAL1 FMAC_FilterConfigTypeDef (InputAccess/OutputAccess) mode selection with explicit IO APIs (HAL_FMAC_WriteX1_* and HAL_FMAC_ReadY_*).

  2. HAL2 uses a clearer split between configuration (HAL_FMAC_SetConfig()) and runtime processes (Write X1 / Read Y / Start filter).